package com.longsys.framework.web.controller;

import com.longsys.framework.server.mongo.MongoCollectionNameUtil;
import com.longsys.framework.server.mongo.MongoEventEntity;
import com.longsys.framework.web.util.DateUtil;
import com.longsys.framework.web.vo.EventQueryVO;
import com.mongodb.BasicDBObject;
import com.mongodb.internal.operation.AggregateOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.aggregation.Aggregation;
import org.springframework.data.mongodb.core.aggregation.LookupOperation;
import org.springframework.data.mongodb.core.aggregation.MatchOperation;
import org.springframework.data.mongodb.core.aggregation.SortOperation;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.stereotype.Controller;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import java.util.Calendar;
import java.util.List;
import java.util.Map;

@RequestMapping("eventAggregate")
@Controller
public class EventAggregateController {


    @Autowired
    private MongoTemplate mongoTemplate;

    @RequestMapping("queryEventList")
    @ResponseBody
    public List<MongoEventEntity> queryEventList(@RequestBody EventQueryVO eventQueryVO) {
        //基础查询(事件查询)
        MatchOperation eventMatchOperation = matchEvent(eventQueryVO);
        //关联聚合
        String aggregateCollectionName = MongoCollectionNameUtil.getAggregateCollectionName(eventQueryVO.getSystem(), eventQueryVO.getAggregateType());
        LookupOperation lookupOperation = Aggregation.lookup(aggregateCollectionName, "aggregateObjectId", "_id", "aggr");
        //聚合查询
        Map<String, Object> aggrMatchMap = eventQueryVO.getAggrMatchMap();
        Criteria criteria = new Criteria();
        criteria.where("aggr._id").not();
        if (aggrMatchMap != null) {
            for (String key : aggrMatchMap.keySet()) {
                Object value = aggrMatchMap.get(key);
                criteria.and("aggr."+key).is(value);
            }
        }
        MatchOperation aggrMatchOperation = Aggregation.match(criteria);
        //排序
        SortOperation sortOperation = Aggregation.sort(Sort.Direction.DESC, "eventTime");

        Aggregation aggregation = Aggregation.newAggregation(eventMatchOperation, lookupOperation, aggrMatchOperation, sortOperation);

        String collectionName = MongoCollectionNameUtil.getEventCollectionName(eventQueryVO.getSystem());
        return mongoTemplate.aggregate(aggregation, collectionName, MongoEventEntity.class).getMappedResults();
    }

    private MatchOperation matchEvent(EventQueryVO eventQueryVO) {
        Criteria criteria = Criteria.where("system").is(eventQueryVO.getSystem());
        if (!StringUtils.isEmpty(eventQueryVO.getEventType())) {
            criteria.and("eventType").is(eventQueryVO.getEventType());
        }
        if (!StringUtils.isEmpty(eventQueryVO.getAggregateType())) {
            criteria.and("aggregateType").is(eventQueryVO.getAggregateType());
        }
        if (eventQueryVO.getEventTimeRange() != null && eventQueryVO.getEventTimeRange().size() == 2) {
            criteria.and("eventTime").gte(eventQueryVO.getEventTimeRange().get(0)).lt(DateUtil.plusDate(eventQueryVO.getEventTimeRange().get(1), 1, Calendar.DATE));
        }
        if (!StringUtils.isEmpty(eventQueryVO.getUserId())) {
            criteria.and("eventUser.id").is(eventQueryVO.getUserId());
        }
        if (!StringUtils.isEmpty(eventQueryVO.getUserName())) {
            criteria.and("eventUser.name").is(eventQueryVO.getUserName());
        }
        return Aggregation.match(criteria);
    }
}
